package com.rdgzs.authority.security;

import java.util.List;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.apache.shiro.web.util.SavedRequest;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.beans.factory.annotation.Autowired;

import com.rdgzs.authority.entity.User;
import com.rdgzs.authority.service.UserService;
import com.rdgzs.framework.constant.SysConstants;
import com.rdgzs.framework.utilsTools.ConfigPropertiesUtils;

public class CaptchaFormAuthenticationFilter extends FormAuthenticationFilter {
	private String captchaParam = SysConstants.CAPTCHA;
	private final static String USER_COL_ID = SysConstants.USER_COL_ID;
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
	}
	
	/**
	 * 得到验证码指定key的值
	 * @param request
	 * @return 从request里取得对应的值
	 */
	protected String getCaptcha(ServletRequest request) {
		return WebUtils.getCleanParam(request, getCaptchaParam());
	}
	
	/**
	 * 创建令牌
	 */
	protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) {
		String username = getUsername(request);
		String password = getPassword(request);
		String captcha = getCaptcha(request);
		boolean rememberMe = isRememberMe(request);
		String host = getHost(request);
		
		return new CaptchaUsernamePasswordToken(username, password.toCharArray(), rememberMe, host, captcha);
	}
	
	/**
	 * 登陆认证
	 */
	protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception {
		AuthenticationToken token = createToken(request, response);
		if (token == null) {
			String msg = "createToken method implementation returned null. A valid non-null AuthenticationToken must be created in order to execute a login attempt.";
			throw new IllegalStateException(msg);
		}
		try {
			// 验证码校验
			doCaptchaValidate( (HttpServletRequest)request,(CaptchaUsernamePasswordToken) token ); 
			
			Subject subject = getSubject(request, response);
			subject.login(token);
			return onLoginSuccess(token, subject, request, response);
		} catch (AuthenticationException e) {
			return onLoginFailure(token, e, request, response);
		}
	}

	// 验证码校验
	protected void doCaptchaValidate(HttpServletRequest request, CaptchaUsernamePasswordToken token) {
		String captcha = (String) request.getSession().getAttribute(captchaParam);
//停掉了验证码认证  当加入验证码时需要开启
//		if (captcha != null && !captcha.equalsIgnoreCase(token.getCaptcha())) {
//			throw new IncorrectCaptchaException("验证码错误！");
//		}
	}

	/**
	 * 覆盖默认实现，用sendRedirect直接跳出框架，以免造成js框架重复加载js出错。
	 * @param token
	 * @param subject
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception  
	 * @see org.apache.shiro.web.filter.authc.FormAuthenticationFilter#onLoginSuccess(org.apache.shiro.authc.AuthenticationToken, org.apache.shiro.subject.Subject, javax.servlet.ServletRequest, javax.servlet.ServletResponse)
	 */
	@Override
	protected boolean onLoginSuccess(AuthenticationToken token, Subject subject, ServletRequest request,
			ServletResponse response) throws Exception {
		String adminAcount = ConfigPropertiesUtils.get(SysConstants.ADMIN_ACCOUNT);//超管帐户
		String adminPassword = ConfigPropertiesUtils.get(SysConstants.ADMIN_PASSWORD);//超管密码
		String adminSalt = ConfigPropertiesUtils.get(SysConstants.ADMIN_SALT);//超管盐值
		String adminName = ConfigPropertiesUtils.get(SysConstants.ADMIN_NAME);//超管名称
		HttpServletRequest req = (HttpServletRequest) request;
		HttpServletResponse res = (HttpServletResponse) response;
		SavedRequest saveReq = WebUtils.getSavedRequest(request);
		String username = getUsername(request);
		User user = new User();
		user.setUserType(SysConstants.ACCOUNT_TYPE_SUPER_ADMIN);//临时：为了下面代码将用户对像保存到 session 中
		
		
		//1.系统超级管理员【帐号信息存储于配置文件：sysConfig.properties】
		if (username.equals(adminAcount)) {
			user.setEmpId("0");
			user.setAccount(adminAcount);
			user.setShowname(adminName);
			user.setUserType(SysConstants.ACCOUNT_TYPE_SUPER_ADMIN);
		}else{//系统用户
			List<User> users=userService.query(USER_COL_ID, username);
 			if(users.size()>0){
				user = users.get(0);
			}
		}
		
		//当登陆成功时保存用户到Session中
		if(user.getUserType()!=null&&user.getUserType().trim().length()>0){
			subject.getSession().setAttribute(SysConstants.CURR_USER, user);
		}

		issueSuccessRedirect(request, response);

		return false;
	}
	
	private UserService userService;
	
	@Autowired
	public void setUserService(UserService userService) {
		this.userService = userService;
	}
	
	public String getCaptchaParam() {
		return captchaParam;
	}
	
	public void setCaptchaParam(String captchaParam) {
		this.captchaParam = captchaParam;
	}
	
}
